package org.smartercontext.contextmger.fixedgatherers;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONObject;
import org.smartercontext.contextmger.DTO.BooksDTO;
import org.smartercontext.contextmger.DTO.MovieDTO;
import org.smartercontext.contextmger.DTO.MusicDTO;
import org.smartercontext.contextmger.DTO.PersonDTO;
import org.smartercontext.contextmger.DTO.StudyDTO;
import org.smartercontext.contextmger.DTO.WorkDTO;

/**
 * This class is an implementation of ISocialGatherer interface.
 * This class allows get the Facebook information.
 * @author JuanPablo
 * @creation_date 07 Mar 2014
 * @version 1.0
 */
public class FacebookGatherer implements ISocialGatherer{
	
	/**
	 * This static variable does reference to the URL address to the
	 * user's authentication on Facebook
	 */
	private static final String fb_oauth="https://www.facebook.com/dialog/oauth?";
	
	/**
	 * This static variable contains the Facebook client_id for the
	 * SmarterContext Social Connect application
	 */
	private static final String client_id="1458031187744557";
	
	/**
	 * This static variable contains the Facebook client_secret for the
	 * SmarterContext Social Connect application
	 */
	private static final String clientSecret="fdb317f43f91485fb13c33d816bb78de";
	
	/**
	 * This static variable contains the Facebook scope for the
	 * SmarterContext Social Connect application. The values saved in it
	 * allows to SmarterContext realize the GET request to Facebook Graph API
	 */
	private static final String scope="email,user_birthday,friends_about_me,user_likes,user_education_history," +
			"user_work_history,user_friends,user_actions.music,user_actions.books,user_actions.video," +
			"user_interests,user_relationship_details,user_relationships,read_friendlists";
	
	/**
	 * This static variable contains the URL for the return of Facebook 
	 * authorization.
	 */
	private static final String redirect_uri="http://smartercontext.org:8080/SmarterContext_Web_Server/RedirectFBServlet";
	
	private static final String urlGraph = "https://graph.facebook.com/oauth/access_token?";
	
	private static final String urlUserRequest = "https://graph.facebook.com/";
	
	private ArrayList<ArrayList<Object>>listaPreferencias;
	private String facebookId;
	private String genre;
	private String birthday;
	private String relationShipStatus;
	private String significantOther;
	private ArrayList<Object>tempA;
	
	public FacebookGatherer(){
		listaPreferencias=new ArrayList<ArrayList<Object>>();
		facebookId="";
		genre="";
		birthday="";
		relationShipStatus="";
		significantOther="";
		tempA=new ArrayList<>();
	}
		

	@Override
	public String getFriendList(String token) {
		
		return urlUserRequest+"me?fields=friends&"+token;
	}

	@Override
	public String getEducationList(String token) {
		
		return urlUserRequest+"me?fields=education&"+token;
	}

	@Override
	public String getSportsList(String token) {
		
		return urlUserRequest+"me?fields=sports&"+token;
	}

	@Override
	public String getWorkList(String token) {
		
		return urlUserRequest+"me?fields=work&"+token;
	}

	@Override
	public String getFamilyList(String token) {
		
		return urlUserRequest+"me?fields=family&"+token;
	}

	@Override
	public String getMoviesList(String token) {
		
		return urlUserRequest+"me?fields=movies&"+token;
	}

	@Override
	public String getMusicList(String token) {
		
		return urlUserRequest+"me?fields=music&"+token;
	}

	@Override
	public String getBooksList(String token) {
		
		return urlUserRequest+"me?fields=books&"+token;
	}

	@Override
	public String getBasicInformaction(String token) {
				
		return urlUserRequest+"me?"+token;
	}
	@Override
	public String getSignificantOther (String token){
		
		return urlUserRequest+"me?fields=significant_other&"+token;
	}
	
	public static String getURLLogin(){
		
		String urlLogin="";
		
		try {
			urlLogin = fb_oauth+"client_id="+client_id+"&redirect_uri="
					+ URLEncoder.encode(redirect_uri, "UTF-8")+"&scope="+scope;
		} catch (UnsupportedEncodingException e) {
			
			urlLogin = "Error";
		}
		
		return urlLogin;
	}
	
	public static String getURLUserGraph(String code){
		
		String userGraph = "";
		
		try {
			 userGraph= urlGraph+"client_id="+client_id+"&redirect_uri="
							+ URLEncoder.encode(redirect_uri, "UTF-8")+"&client_secret="
							+clientSecret+"&code="+code;
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			userGraph = "Error";
		}
		return userGraph;
	}
	
	@Override
	public void updateBasicInformation(JSONObject basicInf)throws Exception{
		
		if(basicInf.length()<=1){
			
			throw new Exception();
			
		}else{
		
			facebookId = basicInf.get("id").toString();
			
			boolean genr = basicInf.has("gender");
			
			if(genr){
				genre = basicInf.get("gender").toString();
			}
			
			boolean birht = basicInf.has("birthday");
			
			if(birht){
				birthday = basicInf.get("birthday").toString();
			}
			
			boolean rel=basicInf.has("relationship_status");
			
			if(rel){
				relationShipStatus = basicInf.get("relationship_status").toString();
			}
		
		}
		
	}
	@Override
	public void updateSignificantOther(JSONObject signifInf) throws Exception {
		
		if(signifInf.length()>1){
			significantOther = signifInf.get("significant_other").toString();
		}
		
		
	}
	@Override
	public void updateStudyInforrmatin(JSONObject studiesInf)throws Exception{
		
		if(studiesInf.length()>1){
			
			ArrayList<Object>studiedAt = new ArrayList<>();
		
			JSONArray array = studiesInf.getJSONArray("education");
			
			for(int i=0;i<array.length();i++){
				JSONObject values = (JSONObject) array.get(i);
				StudyDTO temp = new StudyDTO();
				JSONObject school = values.getJSONObject("school");
				String nameS = school.getString("name");
				String type = values.getString("type");
				JSONObject year = values.getJSONObject("year");
				String nameY = year.getString("name");
				
				temp.setSchoolName(nameS);
				temp.setSchoolType(type);
				temp.setEndYear(nameY);
				studiedAt.add(temp);
				
			}
			
			listaPreferencias.add(0,studiedAt);
		
		}
		
	}
	@Override
	public void updateWorkInformation(JSONObject workInf)throws Exception{
		
		if(workInf.length()>0){
			
			ArrayList<Object>work = new ArrayList<>();
			
			JSONArray array = workInf.getJSONArray("work");
			
			for(int i=0;i<array.length();i++){
				JSONObject obj = array.getJSONObject(i);
				
				JSONObject employer = null;
				
				if(obj.has("employer")){
					employer =  obj.getJSONObject("employer");;
				}
				
				JSONObject location = null;
				
				if(obj.has("location")){
					location = obj.getJSONObject("location");
				}
				
				JSONObject position = null;
				
				if(obj.has("position")){
					position = obj.getJSONObject("position");
				}
				
				String startDate = "";
				 
				if(obj.has("start_date")){
					startDate = obj.getString("start_date");
				}
				
				
				String endDate = "";
				if(obj.has("end_date")){
					endDate = obj.getString("end_date");
				}
				
				String employerName = "";
				
				if(employer!=null&&employer.has("name")){
					employerName = employer.getString("name");
				}
				
				String employerLoc = "";
				
				if(location!=null&&location.has("name")){
					employerLoc = location.getString("name");;
				}
				 
				String positionName = "";
				if(position!=null&&position.has("name")) {
					positionName = position.getString("name");
				
				}
				
				if(employer!=null){
				
					WorkDTO temp = new WorkDTO(employerName, employerLoc, positionName, startDate, endDate);
					work.add(temp);
				
				}
				
			}
			listaPreferencias.add(6, work);
		}
	}
	@Override
	public void updateFamiliInformation(JSONObject familyInf)throws Exception{
		
		if(familyInf.length()>1){
			
			ArrayList<Object>family = new ArrayList<>();
			
			JSONObject familyO = familyInf.getJSONObject("family");
			
			JSONArray array = familyO.getJSONArray("data");
			
			for(int i=0;i<array.length();i++){
				JSONObject obj = array.getJSONObject(i);
				String fbId = obj.getString("id");
				String name = obj.getString("name");
				String rel = obj.getString("relationship");
				
				PersonDTO temp = new PersonDTO(fbId,name,rel);
				
				family.add(temp);
				tempA.add(temp);
			}
			
			listaPreferencias.add(1, family);
			
		}
		
	}
	@Override
	public void updateFriendsInformation(JSONObject friendsInf)throws Exception{
		
		if(friendsInf.length()>1){
			
			ArrayList<Object>friends = new ArrayList<>();
			
			JSONObject friendsO = friendsInf.getJSONObject("friends");
			
			JSONArray array = friendsO.getJSONArray("data");
			
			for(int i=0;i<array.length();i++){
				JSONObject obj = array.getJSONObject(i);
				String fbId = obj.getString("id");
				String name = obj.getString("name");
				
				boolean exists = false;
				
				for(int j=0;j<tempA.size();j++){
					PersonDTO tempFam = (PersonDTO) tempA.get(j);
					
					if(tempFam.getFacebookId().equals(fbId)){
						exists = true;
						break;
					}
				}
				
				if(exists == false){
					PersonDTO friend = new PersonDTO();
					friend.setFacebookId(fbId);
					friend.setName(name);
					friends.add(friend);
				}
			}
			
			listaPreferencias.add(2, friends);
			
		}
		
	}
	@Override
	public void updateMusicInformation(JSONObject musicInf)throws Exception{
		
		if(musicInf.length()>1){
			
			ArrayList<Object>music = new ArrayList<>();
			
			JSONObject musicO = musicInf.getJSONObject("music");
			
			JSONArray array = musicO.getJSONArray("data");
			
			for(int i=0;i<array.length();i++){
				JSONObject obj = array.getJSONObject(i);
				String category = obj.getString("category");
				String name = obj.getString("name");
				String created_time = obj.getString("created_time");
				String fbId = obj.getString("id");
				
				MusicDTO temp = new MusicDTO(fbId, name, category, created_time);
				music.add(temp);
			}
			
			listaPreferencias.add(4, music);
		}
		
	}
	@Override
	public void updateMoviesInformation(JSONObject moviesInf)throws Exception{
		
		if(moviesInf.length()>1){
			
			ArrayList<Object>moviesA = new ArrayList<>();
			
			JSONObject moviesO = moviesInf.getJSONObject("movies");
			
			JSONArray array = moviesO.getJSONArray("data");
			
			for(int i=0;i<array.length();i++){
				JSONObject obj = array.getJSONObject(i);
				String category = obj.getString("category");
				String name = obj.getString("name");
				String created_time = obj.getString("created_time");
				String fbId = obj.getString("id");
				
				MovieDTO temp = new MovieDTO(category, name, created_time, fbId);
				
				moviesA.add(temp);
			}
			
			listaPreferencias.add(3, moviesA);
			
		}
		
	}
	@Override
	public void updateBooksInformation (JSONObject booksInf)throws Exception{
		
		if(booksInf.length()>1){
			
			ArrayList<Object>books = new ArrayList<>();
			
			JSONObject booksO = booksInf.getJSONObject("books");
			
			JSONArray array = booksO.getJSONArray("data");
			
			for(int i=0;i<array.length();i++){
				JSONObject obj = array.getJSONObject(i);
				String fbId = obj.getString("id");
				String name = obj.getString("name");
				String category = obj.getString("category");
				String created_time = obj.getString("created_time");
				
				BooksDTO temp = new BooksDTO(fbId, name, category, created_time);
				
				books.add(temp);
			}
			
			listaPreferencias.add(5, books);
		}
	}


	public ArrayList<ArrayList<Object>> getListaPreferencias() {
		return listaPreferencias;
	}


	public void setListaPreferencias(ArrayList<ArrayList<Object>> listaPreferencias) {
		this.listaPreferencias = listaPreferencias;
	}


	public String getFacebookId() {
		return facebookId;
	}


	public void setFacebookId(String facebookId) {
		this.facebookId = facebookId;
	}


	public String getGenre() {
		return genre;
	}


	public void setGenre(String genre) {
		this.genre = genre;
	}


	public String getBirthday() {
		return birthday;
	}


	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}


	public String getRelationShipStatus() {
		return relationShipStatus;
	}


	public void setRelationShipStatus(String relationShipStatus) {
		this.relationShipStatus = relationShipStatus;
	}


	public String getSignificantOther() {
		return significantOther;
	}


	public void setSignificantOther(String significantOther) {
		this.significantOther = significantOther;
	}


	
	
	

}
